## Example: A Goppa code that corrects up to 3 errors

from PyM import *


# def alternant_decoder(y,C):
#     if not isinstance(y,list) and not isinstance(y,Vector_type):
#         return 'AD error: wrong input type'
#     K = K_(C)
#     if K_(y) != K:
#         if is_sub_domain(K,K_(y)):
#             if isinstance(y,list): y = vector(K,y)
#             if not isinstance(y,Vector_type):
#                 return "AD error: Argument is not a vector"
#         else:
#             return "AD error: Fields of argument and code incompatible"
#     else: 
#         if isinstance(y,list): y = vector(K,y)
#         if not isinstance(y,Vector_type):
#             return "AD error: Argument is not a vector"
#     
#     h = h_(C)
#     if len(y) != len(h):
#         return "AD error: Vector argument has wrong length"
#     r = r_(C); a = a_(C); b = b_(C)
#     H = H_(C); K1 = K_(H)
#     y1 = pull(y,K)
#     s = y1*H.transpose()
#     
#     if is_zero(s): 
#         print("AD: Input is a code vector")
#         return y1
#     [_,z] = polynomial_ring(K1,'z','K[z]')
#     S = polynomial(s,z)
#     
#     if degree(S)< r//2 or trailing_degree(S)>= r//2:
#         return "AD: Non-decodable vector: extraneous syndrome"
#         
#     (L,E)=sugiyama(z**r,S,r//2)
#     M = zero_positions(L,b)
#     if len(M)< degree(L): return 'AD error: undecodable vector: too few roots'
#     
#     if K == Zn(2):
#         for j in range(len(M)):
#             y1[M[j]] += 1 
#         show('Corrected positions:',M)
#         return y1
#     
#     if len(M)<degree(L):
#         return "AD error: non-decodable vector: too few locator roots"
#     L = der(L)
#     err = []
#     for m in M:
#         x = (a[m]*evaluate(E,b[m]))/(h[m]*evaluate(L,b[m]))
#         x = pull(x,K)
#         if not belongs(x,K):
#             return "AD error: Non-decodable vector: Forney value not in base field"
#         err += [-x]
#         y1[m] = y1[m]+x
#     if is_zero(y1*H.transpose()):
#         print("AD: Successful decoding with error table:\n",M,'\n',vector(err))
#         return y1
#     else: return "AD error: output vector has non-zero syndrome"
# # alias
# BMS = AD = alternant_decoder
# 
# 
# def GF(q,alpha='x'):
#     if not is_prime_power(q): 
#         return 'GF error: cardinal is not a prime power'
#     P = prime_factors(q)
#     p = P[0]; m = len(P)
#     f = get_irreducible_polynomial(Zn(p),m)
#     [F,x] = extension(Zn(p),f,alpha)
#     return [F,x]
# 

K = Zn(2)
[F,t] = GF(2**4,'t')  # F16 = K[t]
n = cardinal(F)-1

[_,X] = polynomial_ring(F, 'X')

g = X**6

a = [element(j,F) for j in range(1,n+1)]

C = goppa(g,a)

y = vector(F,[0,1,1,0,0,0,0,0,0,0,0,0,0,0,1])

x1 = BMS(y,C)
show(x1)

y = vector(F,[0,1,1,0,0,1,0,0,0,0,0,0,0,0,1])
show('y =',y)
x2 = BMS(y,C)
show(x2)
show(BMS(x2,C))
# since x2 has weight 7, d_C = 7

y = x2 + vector(Zn(2),eps(n,6))
show('y =',y)
x3 = BMS(y,C)
show(x3)

y = y + vector(Zn(2),eps(n,9))
show('y =',y)
x4 = BMS(y,C)
show(x4)

y = y + vector(Zn(2),eps(n,11))
show('y =',y)
x5 = BMS(y,C)
show(x5)

y = vector(K,[0,1,1,0,0,1,0,0,0,1,0,0,0,0,1])
show('y =',y)
x6 = BMS(y,C)
show('x6 =',x6)
show(BMS(x6,C))

















